#ifndef TASKSCHEDULER_H_
#define TASKSCHEDULER_H_

#include "Job.h"
#include "DataLinkedList.h"

class TaskScheduler {
protected:
	class JobLinkedList: public DataLinkedList {
	protected:
		JobLinkedList(const JobLinkedList& listToCopy): DataLinkedList(listToCopy) { }

	public:
		JobLinkedList();
		virtual ~JobLinkedList();
		void internalAdd(Job& newData, const Iterator& positionHolder);

		void print(const int time, const int type); // TODO DEBUG!!!
	};
	JobLinkedList& m_listByTime;
	JobLinkedList& m_jobsToRunList;

	TaskScheduler(const TaskScheduler& schedToCopy) : m_listByTime(schedToCopy.m_listByTime), m_jobsToRunList(schedToCopy.m_jobsToRunList) { }

	bool runsBefore(const Job& firstJobOperand, const Job& secondJobOperand) const;
	void addRoundRobin(Job& newJob); // TODO DELETE!!!
	virtual Job& duplicateJob(const Job&) const = 0;
	virtual Job& createJob(const unsigned int startTime, const unsigned int length, const int priority) const = 0;
	void addRoundRobin(DataLinkedList::Iterator& readyJobsItr, Job& currJobCopy);

	void sortRoundRobin();

	/*void*/ bool executeJob(const int systemTime, const int type);

public:
	TaskScheduler();
	virtual ~TaskScheduler() = 0;
	//void addJob(Job& newJob);
	/***************************************************************************************
	* function name: void addJob(const unsigned int startTime, const unsigned int length, const int priority)
	* The Input: New job's attributes
	* The output: None
	* The Function operation: Creates a new job with given attributes and adds it to job list
	***************************************************************************************/
	void addJob(const unsigned int startTime, const unsigned int length, const int priority);

	/*void*/ bool work(const int systemTime, const int type);

	bool isEmpty() const;
};

#endif
